/*
  LinPVR - Linux Personal Video Recorder
  Copyright (C) 2006 Kamil Pawlowski <kamilpe@gmail.com>

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include "gui.h"
#include "debug.h"

void show_devices_list(GladeXML *glade, GtkWindow *parent)
{
  GtkWindow *devwin     = GTK_WINDOW(glade_xml_get_widget(glade,"devices"));
  GtkTreeView *formats  = GTK_TREE_VIEW(glade_xml_get_widget(glade,"devices_list"));
  GtkListStore *store   = GTK_LIST_STORE(gtk_tree_view_get_model(formats));

  struct dirent *dir;
  DIR *dev = opendir("/dev");

  gtk_list_store_clear(store);
  while ((dir = readdir(dev))) {
    if (!strncmp(dir->d_name,"video",5)) {
      char card[32];
      char full_path[256];
      GtkTreeIter iter;
      videodev_t videodev;

      g_sprintf(full_path, "/dev/%s", dir->d_name);

      if (videodev_open(&videodev, full_path) < 0) continue;
      g_strlcpy(card, videodev.cap.card, 32);
      videodev_close(&videodev);
      
      gtk_list_store_append(store, &iter);
      gtk_list_store_set(store, &iter, 
			 0, card,
			 1, full_path,
			 -1);
    }
  }

  closedir(dev);
  gtk_widget_show(GTK_WIDGET(devwin));
  gtk_window_set_transient_for(devwin, parent);
}

void show_videodev_info(GladeXML *glade, GtkWindow *parent, videodev_t *video)
{
#define TOGGLED(id, widget)   \
  if (entry_bus,video->cap.capabilities & id) \
    gtk_toggle_button_set_active(widget, TRUE); \
  else \
    gtk_toggle_button_set_active(widget, FALSE);

  struct v4l2_fmtdesc fmtdesc;
  char version[10];

  GtkWindow *capwin        = GTK_WINDOW(glade_xml_get_widget(glade,"capabilities"));
  GtkEntry  *entry_device  = GTK_ENTRY(glade_xml_get_widget(glade,"entry_device"));
  GtkEntry  *entry_card    = GTK_ENTRY(glade_xml_get_widget(glade,"entry_card"));
  GtkEntry  *entry_driver  = GTK_ENTRY(glade_xml_get_widget(glade,"entry_driver"));
  GtkEntry  *entry_bus     = GTK_ENTRY(glade_xml_get_widget(glade,"entry_bus"));
  GtkEntry  *entry_version = GTK_ENTRY(glade_xml_get_widget(glade,"entry_version"));
  GtkTreeView *formats     = GTK_TREE_VIEW(glade_xml_get_widget(glade,"formats_list"));
  GtkListStore *store      = GTK_LIST_STORE(gtk_tree_view_get_model(formats));
  GtkToggleButton *cap_video_capture = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_video_capture"));
  GtkToggleButton *cap_video_output  = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_video_output"));
  GtkToggleButton *cap_video_overlay = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_video_overlay"));
  GtkToggleButton *cap_vbi_capture   = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_vbi_capture"));
  GtkToggleButton *cap_vbi_output    = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_vbi_output"));
  GtkToggleButton *cap_tuner         = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_tuner"));
  GtkToggleButton *cap_audio         = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_audio"));
  GtkToggleButton *cap_readwrite     = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_readwrite"));
  GtkToggleButton *cap_asyncio       = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_asyncio"));
  GtkToggleButton *cap_streaming     = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_streaming"));
  GtkToggleButton *cap_rds_capture   = GTK_TOGGLE_BUTTON(glade_xml_get_widget(glade,"cap_rds_capture"));

  g_sprintf(version,"%-10d",video->cap.version);
  gtk_entry_set_text(entry_card,video->cap.card);
  gtk_entry_set_text(entry_driver,video->cap.driver);
  gtk_entry_set_text(entry_bus,video->cap.bus_info);
  gtk_entry_set_text(entry_version,version);

  TOGGLED (V4L2_CAP_VIDEO_CAPTURE, cap_video_capture);
  TOGGLED (V4L2_CAP_VIDEO_OUTPUT, cap_video_output);
  TOGGLED (V4L2_CAP_VIDEO_OVERLAY, cap_video_overlay);
  TOGGLED (V4L2_CAP_VBI_CAPTURE, cap_vbi_capture);
  TOGGLED (V4L2_CAP_VBI_OUTPUT, cap_vbi_output);
  TOGGLED (V4L2_CAP_TUNER, cap_tuner);
  TOGGLED (V4L2_CAP_AUDIO, cap_audio);
  TOGGLED (V4L2_CAP_READWRITE, cap_readwrite);
  TOGGLED (V4L2_CAP_ASYNCIO, cap_asyncio);
  TOGGLED (V4L2_CAP_STREAMING, cap_streaming);
  TOGGLED (V4L2_CAP_RDS_CAPTURE, cap_rds_capture);

  memset(&fmtdesc, 0, sizeof(fmtdesc));
  fmtdesc.index = 0;
  fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  gtk_list_store_clear(store);

  while (ioctl(video->fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
    GtkTreeIter iter;
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, fmtdesc.description, -1);
    fmtdesc.index ++;
  }

  gtk_window_set_transient_for(capwin, parent);
  gtk_widget_show(GTK_WIDGET(capwin));
}

void show_error_report(GladeXML *glade, const char *message)
{
  GtkDialog *dialog;
  GtkTextView *textview;
  GtkTextBuffer *text;

  dialog = GTK_DIALOG(glade_xml_get_widget(glade, "error_report"));
  textview = GTK_TEXT_VIEW(glade_xml_get_widget(glade, "message"));

  text = gtk_text_view_get_buffer(textview);
  gtk_text_buffer_set_text(text, message , -1);

  gtk_dialog_run(dialog);
  gtk_widget_hide(GTK_WIDGET(dialog));
}

void prepare_library_tree(GtkTreeView *tree)
{
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkListStore *store;

  renderer = gtk_cell_renderer_text_new();
  store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
  gtk_tree_view_set_model(tree, GTK_TREE_MODEL(store));
  
  column = gtk_tree_view_column_new_with_attributes ("Name",renderer,"text",COL_LIB_NAME,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_LIB_NAME);
  gtk_tree_view_append_column(tree, column);

  column = gtk_tree_view_column_new_with_attributes ("Date",renderer,"text",COL_LIB_DATE,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_LIB_DATE);
  gtk_tree_view_append_column(tree, column);

  column = gtk_tree_view_column_new_with_attributes ("Length",renderer,"text",COL_LIB_LENGTH,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_LIB_LENGTH);
  gtk_tree_view_append_column(tree, column);

  gtk_tree_view_columns_autosize(tree);
}

void prepare_formats_tree(GtkTreeView *tree)
{
  GtkTreeViewColumn *column;
  GtkListStore *store;
  store = gtk_list_store_new(1, G_TYPE_STRING);
  gtk_tree_view_set_model(tree, GTK_TREE_MODEL(store));
  column = gtk_tree_view_column_new_with_attributes (NULL,gtk_cell_renderer_text_new(),
						     "text", 0, NULL);
  gtk_tree_view_append_column(tree, column);
}

void prepare_devices_tree(GtkTreeView *tree)
{
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkListStore *store;

  renderer = gtk_cell_renderer_text_new();

  store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
  gtk_tree_view_set_model(tree, GTK_TREE_MODEL(store));

  column = gtk_tree_view_column_new_with_attributes ("Name", renderer, "text", 0, NULL);
  gtk_tree_view_append_column(tree, column);
  column = gtk_tree_view_column_new_with_attributes ("Device", renderer, "text", 1, NULL);
  gtk_tree_view_append_column(tree, column);
}

void prepare_channels_tree(GtkTreeView *tree)
{
  GtkTreeViewColumn *column;
  GtkListStore *store;
  store = gtk_list_store_new(1, G_TYPE_STRING);
  gtk_tree_view_set_model(tree, GTK_TREE_MODEL(store));
  column = gtk_tree_view_column_new_with_attributes ("Channels",gtk_cell_renderer_text_new(),
						     "text", 0, NULL);
  gtk_tree_view_append_column(tree, column);
}

void prepare_sheduler_tree(GtkTreeView *tree)
{
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkListStore *store;

  renderer = gtk_cell_renderer_text_new();
  store = gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
			     G_TYPE_STRING, G_TYPE_STRING);
  gtk_tree_view_set_model(tree, GTK_TREE_MODEL(store));
  
  column = gtk_tree_view_column_new_with_attributes ("Name",renderer,"text",COL_SHD_NAME,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_SHD_NAME);
  gtk_tree_view_append_column(tree, column);

  column = gtk_tree_view_column_new_with_attributes ("Channel",renderer,"text",COL_SHD_CHANNEL,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_SHD_CHANNEL);
  gtk_tree_view_append_column(tree, column);

  column = gtk_tree_view_column_new_with_attributes ("Start record",renderer,"text",COL_SHD_START,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_SHD_START);
  gtk_tree_view_append_column(tree, column);

  column = gtk_tree_view_column_new_with_attributes ("Stop record",renderer,"text",COL_SHD_STOP,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_SHD_STOP);
  gtk_tree_view_append_column(tree, column);

  column = gtk_tree_view_column_new_with_attributes ("Quality",renderer,"text",COL_SHD_QUALITY,NULL);
  gtk_tree_view_column_set_resizable(column, 1);
  gtk_tree_view_column_set_sort_column_id(column, COL_SHD_QUALITY);
  gtk_tree_view_append_column(tree, column);

  gtk_tree_view_columns_autosize(tree);
}

void set_properties_by_gui(GladeXML *glade, capture_t *capture)
{
  capture->fps    = 25;
  capture->vb     = 728;
}

gboolean preview_update(preview_t *preview)
{
  capture_t *capture = preview->capture;

  if (GDK_IS_DRAWABLE(GDK_DRAWABLE(GTK_WIDGET(preview->area)->window)) &&
      capture->state == CAPTURE_WORK && capture->video_proc.frame_ready) {

    preview->pixbuf = gdk_pixbuf_new_from_data(capture->video_proc.rgb_buffer,
					       GDK_COLORSPACE_RGB, FALSE,
					       8, capture->width, capture->height, 
					       capture->width * 3, NULL, NULL);
    
    gdk_draw_pixbuf(GDK_DRAWABLE(GTK_WIDGET(preview->area)->window), 
		    NULL, preview->pixbuf, 0, 0, 0, 0,
		    capture->width, capture->height, GDK_RGB_DITHER_NONE, 0, 0);

    if (capture->transfered > 0) {
      char *msg;
      msg = g_strdup_printf("Recording from TV (size: %.3f MB, time: 00:00:00)", (float)capture->transfered/1048576);
      gtk_statusbar_push (preview->statusbar, preview->contextid, msg);
      g_free(msg);
    }
  }

  return TRUE;
}

int preview_init(preview_t *preview, GladeXML *glade)
{
  preview->area = GTK_DRAWING_AREA(glade_xml_get_widget(glade,"preview"));
  preview->statusbar = GTK_STATUSBAR(glade_xml_get_widget(glade, "statusbar"));
  preview->contextid = gtk_statusbar_get_context_id(preview->statusbar, "Application status");
}
